package com.mdd.admin.service.region.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.mdd.admin.service.region.IDevRegionService;
import com.mdd.admin.vo.region.DevRegionListVo;
import com.mdd.common.dto.RegionDto;
import com.mdd.common.dto.result.RegionResultDto;
import com.mdd.common.entity.region.DevRegion;
import com.mdd.common.enums.RegionLevelEnum;
import com.mdd.common.mapper.region.DevRegionMapper;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 地区实现类
 */
@Service
public class DevRegionServiceImpl extends ServiceImpl<DevRegionMapper, DevRegion> implements IDevRegionService {

    @Resource
    DevRegionMapper devRegionMapper;

    private static Map<Long, String> regionMap;

    @Override
    public List<DevRegionListVo> province(int regionLevel) {
        return this.commonList(regionLevel, null);
    }

    @Override
    public List<DevRegionListVo> city(Long provinceId, int regionLevel) {
        return this.commonList(regionLevel, provinceId);
    }

    @Override
    public List<DevRegionListVo> district(Long cityId, int regionLevel) {
        return this.commonList(regionLevel, cityId);
    }

    private List<DevRegionListVo> commonList(Integer regionLevel, Long parentId) {
        List<DevRegionListVo> targetList = new ArrayList<>();
        RegionDto dto = new RegionDto();
        dto.setLevel(regionLevel);
        dto.setParentId(parentId);
        List<RegionResultDto> list = devRegionMapper.list(dto);
        for (RegionResultDto resultDto : list) {
            DevRegionListVo devRegion = new DevRegionListVo();
            BeanUtils.copyProperties(resultDto, devRegion);
            targetList.add(devRegion);
        }
        return targetList;
    }

    @Override
    public List<DevRegionListVo> tree() {
        List<DevRegion> devRegionList = devRegionMapper.selectList(new LambdaQueryWrapper<>());
        if (CollectionUtils.isEmpty(devRegionList)) {
            return Lists.newArrayList();
        }
        return this.buildTree(devRegionList, 0L, RegionLevelEnum.DISTRICT.getCode());
    }

    private List<DevRegionListVo> buildTree(List<DevRegion> allRegion, Long pid, int regionLeve) {
        List<DevRegionListVo> regionTreeList = new ArrayList<>();
        //获取省
        if (regionLeve == RegionLevelEnum.PROVINCE.getCode()) {
            List<DevRegion> regionList = allRegion.stream().filter(region -> region.getLevel().equals(RegionLevelEnum.PROVINCE.getCode())).collect(Collectors.toList());
            for (DevRegion region : regionList) {
                DevRegionListVo regionTree = new DevRegionListVo();
                BeanUtils.copyProperties(region, regionTree);
                regionTreeList.add(regionTree);
            }
        } else if (regionLeve == RegionLevelEnum.CITY.getCode()) {
            //获取省市
            List<DevRegion> regionList = allRegion.stream().filter(region -> region.getLevel().equals(1) || region.getLevel().equals(2)).collect(Collectors.toList());
            for (DevRegion region : regionList) {
                if (Objects.equals(pid, region.getParentId())) {
                    DevRegionListVo regionTree = new DevRegionListVo();
                    BeanUtils.copyProperties(region, regionTree);
                    regionTree.setChildList(buildTree(allRegion, region.getId(), regionLeve));
                    regionTreeList.add(regionTree);
                }
            }
        } else {
            //获取省市区
            for (DevRegion region : allRegion) {
                if (Objects.equals(pid, region.getParentId())) {
                    DevRegionListVo regionTree = new DevRegionListVo();
                    BeanUtils.copyProperties(region, regionTree);
                    regionTree.setChildList(buildTree(allRegion, region.getId(), regionLeve));
                    regionTreeList.add(regionTree);
                }
            }
        }
        return regionTreeList;
    }

    @Override
    public Map<Long, String> getRegionMap() {
        if (!org.springframework.util.CollectionUtils.isEmpty(regionMap)) {
            return regionMap;
        }
        List<DevRegion> list = super.list();
        if (CollectionUtils.isEmpty(list)) {
            return Maps.newHashMap();
        }
        regionMap = list.stream().collect(Collectors.toMap(item -> item.getId(), item -> item.getName(), (a, b) -> b));
        return regionMap;
    }

    @Override
    public void delCache() {
        regionMap = null;
    }

    @PostConstruct
    public void cacheData() {
        List<DevRegion> list = devRegionMapper.selectAll();
        if (CollectionUtils.isNotEmpty(list)) {
            regionMap = list.stream().collect(Collectors.toMap(item -> item.getId(), item -> item.getName(), (a, b) -> b));
        }
    }

}
